/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.sf.fast.ibatis.build; import java.util.HashMap; import java.util.List; import java.util.Map; import net.sf.fast.ibatis.model.FastIbatisConfig; import net.sf.fast.ibatis.util.Utils; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.dom.AST; import org.eclipse.jdt.core.dom.ASTParser; import org.eclipse.jdt.core.dom.Block; import org.eclipse.jdt.core.dom.CompilationUnit; import org.eclipse.jdt.core.dom.Javadoc; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.MethodInvocation; import org.eclipse.jdt.core.dom.Modifier; import org.eclipse.jdt.core.dom.PrimitiveType; import org.eclipse.jdt.core.dom.ReturnStatement; import org.eclipse.jdt.core.dom.SingleVariableDeclaration; import org.eclipse.jdt.core.dom.StringLiteral; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.formatter.CodeFormatter; import org.eclipse.jdt.internal.core.util.SimpleDocument; import org.eclipse.jdt.internal.formatter.DefaultCodeFormatter; import org.eclipse.jface.text.IDocument; import org.eclipse.text.edits.TextEdit; /** * <p> * The main code builder. * it will generate the method definition including method name * method parameters and return type. * </p> * * @author trami * @version 1.0 */ public abstract class AbstractCodeBuilder implements CodeBuilder { /** * <p> * the method content generated in the subclass. * </p> * @param ast the ast * @param fc the configuration to generate * @return the code block */ public abstract Block createBlock(AST ast,FastIbatisConfig fc); /** * <p> * Now we can generate 2 Categories * </p> * @return 1 = Service Category. * 2 = DAO Category. */ public abstract int getGenerateCategory(); @SuppressWarnings("unchecked") private MethodDeclaration createMethodDeclaration(AST ast,TypeDeclaration type,FastIbatisConfig fc) { MethodDeclaration methodDeclaration = ast.newMethodDeclaration(); methodDeclaration.setConstructor(false); List modifiers = methodDeclaration.modifiers(); modifiers.add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); methodDeclaration.setName(ast.newSimpleName(fc.getMethodName())); String _str = fc.getReturnType(); if(_str==null||_str.equalsIgnoreCase("void")) methodDeclaration.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); else methodDeclaration.setReturnType2(ast.newSimpleType(ast.newSimpleName(_str))); SingleVariableDeclaration variableDeclaration = ast.newSingleVariableDeclaration(); variableDeclaration.setType(ast.newSimpleType(ast.newSimpleName(fc.getParamType()))); variableDeclaration.setName(ast.newSimpleName("param")); methodDeclaration.parameters().add(variableDeclaration); return methodDeclaration; } private MethodDeclaration createMethodDeclaration(AST ast,TypeDeclaration type,String returnStr, String methodName, Map<String, String> parameters) { MethodDeclaration methodDeclaration = ast.newMethodDeclaration(); methodDeclaration.setConstructor(false); List modifiers = methodDeclaration.modifiers(); modifiers.add(ast.newModifier(Modifier.ModifierKeyword.PUBLIC_KEYWORD)); methodDeclaration.setName(ast.newSimpleName(methodName)); if(returnStr==null||returnStr.equalsIgnoreCase("void")) { methodDeclaration.setReturnType2(ast.newPrimitiveType(PrimitiveType.VOID)); } else { methodDeclaration.setReturnType2(TypeGenerator.getType(ast, returnStr)); } for (String pType : parameters.keySet()) { String pName = parameters.get(pType); SingleVariableDeclaration variableDeclaration = ast.newSingleVariableDeclaration(); variableDeclaration.setType(TypeGenerator.getType(ast, pType)); variableDeclaration.setName(ast.newSimpleName(pName)); methodDeclaration.parameters().add(variableDeclaration); } return methodDeclaration; } public Block createServiceBlock(AST ast, Map<String, String> paramMapping, String methodName, String modelName) { Block block = ast.newBlock(); MethodInvocation methodInvocation = ast.newMethodInvocation(); methodInvocation.setExpression(ast.newName(modelName)); methodInvocation.setName(ast.newSimpleName(methodName)); for(String key : paramMapping.keySet()) { methodInvocation.arguments().add(ast.newSimpleName(paramMapping.get(key))); } ReturnStatement rs = ast.newReturnStatement(); rs.setExpression(methodInvocation); block.statements().add(rs); return block; } public Map<String,String> generateCode(FastIbatisConfig fc) { Map<String,String> ret = new HashMap<String,String>(); try { GenerateFileType interfaceType = null; GenerateFileType implType = null; if(getGenerateCategory()==1) { interfaceType = GenerateFileType.Service_Interface; implType = GenerateFileType.Service_Implementation; } else if(getGenerateCategory()==2) { interfaceType = GenerateFileType.DAO_Interface; implType = GenerateFileType.DAO_Implementation; } ICompilationUnit SrvInterface_cu = JavaCore.createCompilationUnitFrom(Utils.getSuitableIFile(fc.getXmlFilePath(),fc.getXmlFileName(),interfaceType)); String javaFileName = Utils.convertIbatisXml2JavaFile(fc.getXmlFileName(),interfaceType); final String finalJavaPath = Utils.reduceJavaFilePath(fc.getXmlFilePath(), fc.getXmlFileName(), javaFileName); String code = generateCode(SrvInterface_cu,fc, ""); ret.put(finalJavaPath, code); ICompilationUnit Srv_cu = JavaCore.createCompilationUnitFrom(Utils.getSuitableIFile(fc.getXmlFilePath(),fc.getXmlFileName(),implType)); String javaFileName1 = Utils.convertIbatisXml2JavaFile(fc.getXmlFileName(),implType); final String finalJavaPath1 = Utils.reduceJavaFilePath(fc.getXmlFilePath(), fc.getXmlFileName(), javaFileName1); String code1 = generateCode(Srv_cu,fc, ""); ret.put(finalJavaPath1, code1); }catch(Exception e) { } return ret; } /** * generate mybatis code */ public String generateCode(ICompilationUnit cu, FastIbatisConfig fc) { if(cu == null) return null; if (Utils.isMethodExist(cu, fc.getMethodName())) { return "N/A"; } ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setSource(cu); // parser.setResolveBindings(false); CompilationUnit astRoot = (CompilationUnit) parser.createAST(null); AST ast = astRoot.getAST();// AST.newAST(AST.JLS3); TypeDeclaration type = ((TypeDeclaration) astRoot.types().get(0)); Map<String, String> paramMapping = TypeGenerator.getParameterMap(fc.getParamType()); fc.setParamMapping(paramMapping); MethodDeclaration methodDeclaration = createMethodDeclaration(ast,type,fc.getReturnType(), fc.getMethodName(), paramMapping); if(type.isInterface()) { } else { Block block = createServiceBlock(ast, paramMapping, fc.getMethodName(), fc.getMapperName()); methodDeclaration.setBody(block); } if (fc.getMethodComment() != null && fc.getMethodComment().length() > 0) { Javadoc jc = Utils.getJavadoc(ast, fc.getMethodComment()); if(jc!=null) methodDeclaration.setJavadoc(jc); } type.bodyDeclarations().add(methodDeclaration); String str = astRoot.toString(); IDocument document = new SimpleDocument(str); //writeContent(fileName,newSource); Map options = cu.getJavaProject().getOptions(true); CodeFormatter formatter = new DefaultCodeFormatter(options); int indentationLevel= 0;//StringUtils.inferIndentationLevel(" ", getTabSize()); TextEdit textEdit = formatter.format(CodeFormatter.K_COMPILATION_UNIT, str, 0, str.length(), indentationLevel, "\n"); try { textEdit.apply(document, TextEdit.NONE); String result = document.get(); return result; } catch (Exception e) { } return null; } @SuppressWarnings("unchecked") private String generateCode(ICompilationUnit cu,FastIbatisConfig fc, String signature) { if(cu==null||Utils.isMethodExist(cu,fc.getMethodName())) return null; ASTParser parser = ASTParser.newParser(AST.JLS3); parser.setSource(cu); // parser.setResolveBindings(false); CompilationUnit astRoot = (CompilationUnit) parser.createAST(null); AST ast = astRoot.getAST();// AST.newAST(AST.JLS3); TypeDeclaration type = ((TypeDeclaration) astRoot.types().get(0)); MethodDeclaration methodDeclaration = createMethodDeclaration(ast,type,fc); if(type.isInterface()) { } else { Block block = createBlock(ast,fc); methodDeclaration.setBody(block); } Javadoc jc = Utils.getJavadoc(ast,Utils.toHexString(fc.getMethodComment().getBytes())); if(jc!=null) methodDeclaration.setJavadoc(jc); type.bodyDeclarations().add(methodDeclaration); String str = astRoot.toString(); IDocument document = new SimpleDocument(str); //writeContent(fileName,newSource); Map options = cu.getJavaProject().getOptions(true); CodeFormatter formatter = new DefaultCodeFormatter(options); int indentationLevel= 0;//StringUtils.inferIndentationLevel(" ", getTabSize()); TextEdit textEdit = formatter.format(CodeFormatter.K_COMPILATION_UNIT, str, 0, str.length(), indentationLevel, "\n"); try { textEdit.apply(document, TextEdit.NONE); String result = document.get(); return result; } catch (Exception e) { } return null; } }